#ifndef _TIMEDISCR_H_
#define _TIMEDISCR_H_
#include "defs.h"
#include "config.hpp"
#include "geometry.h"
#include "fluid.h"
#include "spaceDiscr.h"
#include "boundConds.h"

class TimeDiscr
{
private:
  // public:
  VarArray<ConsVar_t, 2, 0> cvOld;
  VarArray<real_t, 2, 0> tstep;
  VarArray<ConsVar_t, 2, 0> &cv;
  const VarArray<Area_t, 2, 0> &si;
  const VarArray<Area_t, 2, 0> &sj;
  const VarArray<real_t, 2, 0> &vol;
  const VarArray<DeptVarE_t, 2, 0> &dvE;
  // const VarArray<DeptVarNS_t, 2, 0> &dvNS;
  VarArray<DeptVarNS_t, 2, 0> &dvNS;

  const VarArray<Coord_t, 2, 0> &coord;
  VarArray<ConsVar_t, 2, 0> &rhs;

  const TimeStep_t timeStepType;
  const int numStage;
  const real_t cflNum;
  const std::array<real_t, 5> &ark;
  const TimeDiscrete_t timeDiscType;
  const Equation_t equType;
  const ConvectFlux_t fluxType;

  SpaceDiscr &spaceDiscrt;
  Fluid &flows;
  BoundConds &boundary;

  const int
      imax, // !< max. dimensions in i-direction (0 <= i <= imax); imax = nci + 3
      jmax, // !< max. dimensions in j-direction (0 <= j <= jmax); jmax = ncj + 3
      il,   //  !< index of the 1st dummy cell in i-direction (right side); il = imax - 1
      jl,   //  !< index of the 1st dummy cell in j-direction (top side); jl = jmax - 1
      i2,   //  !< index of the last physical cell in i-direction; i2 = imax - 2 (physical cells start at index 2)
      j2;   // !< index of the last physical cell in j-direction; j2 = jmax - 2 (physical cells start at index 2)
public:
  ~TimeDiscr() = default;
  TimeDiscr(const TimeDiscr &src) = delete;
  TimeDiscr(TimeDiscr &&src) = delete;
  TimeDiscr &operator=(const TimeDiscr &src) = delete;
  TimeDiscr &operator=(TimeDiscr &&src) = delete;

  TimeDiscr(const Config &cfg, const Geometry &geo,
            Fluid &flow, SpaceDiscr &spaceDiscrete,
            BoundConds &boundary);
  void TimeStepEuler(void);
  void TimeStepNS(void);
  void DensityChange2Norm(real_t &drho2Norm,
                          real_t &drhoMax, Coord_t &position);
  // 已经集总了
  void SolveOneStepEuler(void);
  void SolveOneStepNS(void);

  int GetIL(void) { return il; }
  int GetJL(void) { return jl; }
  int GetI2(void) { return i2; }
  int GetJ2(void) { return j2; }
  const VarArray<Coord_t, 2, 0> &GetCoord(void) const { return coord; }
  const VarArray<DeptVarNS_t, 2, 0> &GetDvNS(void) const { return dvNS; }
  const VarArray<DeptVarE_t, 2, 0> &GetDvEu(void) const { return dvE; }
  const VarArray<ConsVar_t, 2, 0> &GetCV(void) const { return cv; }
};

#endif